package com.guoranhao.tool.rpc;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.fastjson.JSON;
import com.guoranhao.tool.utils.LogUtil;
import com.guoranhao.tool.utils.StringUtil;
import com.guoranhao.tool.utils.UUIDUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.util.Map;

@Activate(group = Constants.CONSUMER)
public class RpcClientInterceptor implements Filter {


    private static final Logger logger = LoggerFactory.getLogger(RpcClientInterceptor.class);

    public RpcClientInterceptor() {
    }

    @Override
    public Result invoke(Invoker<?> arg0, Invocation arg1) throws RpcException {
        Result result;
        String reqId = MDC.get("TraceId");
        this.setTraceId(reqId, arg1);
        String[] interfaces;
        try {
            interfaces = arg0.getUrl().getParameter("interface").split("\\.");
            LogUtil.info(logger, "[client][{0}]receive:{1}", (interfaces.length > 0 ? interfaces[interfaces.length - 1] : "")
                    + "." + arg1.getMethodName(), JSON.toJSON(arg1.getArguments()));
            //开始计时
            long beginTime = System.currentTimeMillis();
            result = arg0.invoke(arg1);
            //结束计时
            long endTime = System.currentTimeMillis();
            String address = RpcContext.getContext().getRemoteAddressString();
            String value = "";
            if(result.getValue() != null){
                Object o = JSON.toJSON(result.getValue());
                if(o != null){
                    value = o.toString();
                }
            }
            if (value.length() > 5000) {
                LogUtil.info(logger, "[client][{0}][{1}](T:{2})return:{3}", address,
                        (interfaces.length > 0 ? interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), (endTime - beginTime), value.substring(0, 1000) + "......");
                LogUtil.debug(logger, "[client][{0}][{1}](T:{2})return:{3}", address,
                        (interfaces.length > 0 ? interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), (endTime - beginTime), value);
            } else {
                LogUtil.info(logger, "[client][{0}][{1}](T:{2})return:{3}", address,
                        (interfaces.length > 0 ? interfaces[interfaces.length - 1] : "") + "." + arg1.getMethodName(), (endTime - beginTime), value);
            }
        } finally {
            if (StringUtil.isEmpty(reqId)) {
                MDC.remove("TraceId");
            }
        }
        return result;
    }

    /**
     * 添加traceId
     *
     * @param arg1
     */
    private void setTraceId(String reqId, Invocation arg1) {
        Map<String, String> at = arg1.getAttachments();
        if (StringUtil.isEmpty(reqId)) {
            reqId = UUIDUtil.uuid();
            MDC.put("reqId", reqId);
        }
        at.put("TraceId", reqId);
    }
}